<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节流</title>
</head>
<body>
    <input type="text" id="input">
</body>
<script>
    let inputEle = document.getElementById('input')

    let timer
    function throttleO(e){
        if(timer) return
        timer = setTimeout(()=>{
            console.log(e.target.value)
            clearTimeout(timer)
            timer = null
        }, 500)
    }

    inputEle.oninput = (e)=>{
        console.log('触发了input')
        throttleO(e)
    }

    // 封装节流函数
    /*
        @params
            immediate: 执行时机，是一触发立即执行还是等待一定时间之后执行
    */
    function throttle(fun, delay, immediate=false){
        let timer
        return function(){
            if(timer) return
            const that = this
            if(immediate) fun.apply(that, arguments)
            timer = setTimeout(()=>{
                if(!immediate) fun.apply(that, arguments)
                clearTimeout(timer)
                timer = null
            }, delay)
        }
    }

    
    let fn = throttle((e, a) => {
        console.log(e.target.value, a)
    }, 500, true)

    inputEle.oninput = (e)=>{
        fn(e, 1)
    }

    /*
        外部函数只执行一次，目的是将timer定义为局部变量，并且可以一直存在内存中。
        内部函数是事件处理函数，间隔n秒会执行一次。
    */

    /*
        节流：
            当连续触发某事件时，间隔一定时间执行一次事件处理函数。
            比如设置延迟300ms执行，在这300ms内哪怕触发了100次事件，也只会执行一次事件处理函数。

        可以设计两种执行时机：
            300ms之前执行：一触发，立马执行一次，然后等待300ms不可以执行。
            300ms之后执行：一触发，立即延迟300ms，到时间再执行。

    */

</script>
</html>
